package com.pri.chat.fragment;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.gson.Gson;
import com.netease.nim.uikit.R;
import com.netease.nim.uikit.api.NimUIKit;
import com.netease.nim.uikit.api.model.contact.ContactChangedObserver;
import com.netease.nim.uikit.api.model.main.OnlineStateChangeObserver;
import com.netease.nim.uikit.api.model.user.UserInfoObserver;
import com.netease.nim.uikit.business.recent.RecentContactsCallback;
import com.netease.nim.uikit.business.recent.TeamMemberAitHelper;
import com.netease.nim.uikit.business.recent.adapter.RecentContactAdapter;
import com.netease.nim.uikit.business.uinfo.UserInfoHelper;
import com.netease.nim.uikit.common.CommonUtil;
import com.netease.nim.uikit.common.badger.Badger;
import com.netease.nim.uikit.common.fragment.TFragment;
import com.netease.nim.uikit.common.ui.dialog.CustomAlertDialog;
import com.netease.nim.uikit.common.ui.drop.DropCover;
import com.netease.nim.uikit.common.ui.drop.DropManager;
import com.netease.nim.uikit.common.ui.recyclerview.listener.SimpleClickListener;
import com.netease.nim.uikit.impl.NimUIKitImpl;
import com.netease.nim.uikit.net.StatusBarUtil;
import com.netease.nim.uikit.net.entity.NoticeUnreadNumber;
import com.netease.nimlib.sdk.NIMClient;
import com.netease.nimlib.sdk.Observer;
import com.netease.nimlib.sdk.RequestCallbackWrapper;
import com.netease.nimlib.sdk.ResponseCode;
import com.netease.nimlib.sdk.msg.MsgService;
import com.netease.nimlib.sdk.msg.MsgServiceObserve;
import com.netease.nimlib.sdk.msg.attachment.MsgAttachment;
import com.netease.nimlib.sdk.msg.constant.MsgStatusEnum;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.constant.SessionTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.netease.nimlib.sdk.msg.model.QueryDirectionEnum;
import com.netease.nimlib.sdk.msg.model.RecentContact;
import com.pri.chat.activity.PushMsgActivity;
import com.pri.chat.activity.SearchMemberActivity;
import com.pri.chat.application.APP;
import com.pri.chat.bean.KeyAndValueEntity;
import com.pri.chat.database.greendao.KeyAndValueEntityDao;
import com.vondear.rxtool.RxActivityTool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

/**
 * 最近联系人列表(会话列表)
 * <p/>
 * Created by huangjun on 2015/2/1.
 */
public class RecentContactsFragment extends TFragment {

    // view
    private RecyclerView recyclerView;

    // 最近会话列表
    private List<RecentContact> items;

    private Map<String, RecentContact> cached; // 暂缓刷上列表的数据（未读数红点拖拽动画运行时用）

    private RecentContactAdapter adapter;

    private boolean msgLoaded = false;

    private RecentContactsCallback callback;

    private UserInfoObserver userInfoObserver;
    private TextView title;
    private TextView qkBtn;
    private View jzzLinear;


    private KeyAndValueEntity keyAndValueEntity;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        findViews();

        StatusBarUtil.setTranslucentForImageViewInFragment(getActivity(), 0, getView());
        StatusBarUtil.setLightMode(getActivity());
        keyAndValueEntity = APP.getKeyAndValueEntityDao().queryBuilder().where(KeyAndValueEntityDao.Properties.TypeKey.eq("unreadnum")).build().list().get(0);
        initMessageList();
        initListener();
    }

    private void initListener() {
        editLinear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getActivity().startActivity(new Intent(getContext(), SearchMemberActivity.class));
            }
        });
        systemLinear.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                RxActivityTool.skipActivity(getContext(), PushMsgActivity.class);
                NIMClient.getService(MsgService.class).deleteRecentContact(systemRecentContact);
                NIMClient.getService(MsgService.class).clearChattingHistory(systemRecentContact.getContactId(), systemRecentContact.getSessionType());

            }
        });
        qkBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                clearContact();
            }
        });
        registerObservers(true);
        registerOnlineStateChangeListener(true);
    }

    private TextView tvUnread;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        tvUnread = getActivity().findViewById(com.pri.chat.R.id.unread_num);
        return inflater.inflate(R.layout.nim_recent_contacts, container, false);
    }


    @Override
    public void onDestroy() {
        registerObservers(false);
        registerOnlineStateChangeListener(false);
        DropManager.getInstance().setDropListener(null);
        super.onDestroy();
    }

    /**
     * 查找页面控件
     */
    LinearLayout messages_list_layout;
    View editLinear;
    TextView msgTip;
    View systemLinear;

    private void findViews() {
        recyclerView = findView(R.id.recycler_view);
        title = findView(R.id.title);
        qkBtn = findView(R.id.qkBtn);
        jzzLinear = findView(R.id.jzzLinear);
        editLinear = findView(R.id.editLinear);
        msgTip = findView(R.id.msgTip);
        messages_list_layout = findView(R.id.messages_list_layout);
        systemLinear = findView(R.id.systemLinear);
    }

    /**
     * 初始化消息列表
     */
    private void initMessageList() {
        items = new ArrayList<>();
        jzzLinear.setVisibility(View.VISIBLE);
        cached = new HashMap<>(3);
        // adapter
        adapter = new RecentContactAdapter(recyclerView, items);
        initCallBack();
        adapter.setCallback(callback);
        // recyclerView
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        recyclerView.addOnItemTouchListener(touchListener);


        getHandler().postDelayed(() -> {
            if (msgLoaded) {
                return;
            }
            NIMClient.getService(MsgService.class).queryRecentContacts(50).setCallback(
                    new RequestCallbackWrapper<List<RecentContact>>() {
                        @Override
                        public void onResult(int code, List<RecentContact> recents, Throwable exception) {
                            if (code != ResponseCode.RES_SUCCESS || recents == null) {
                                return;
                            }
                            // 此处如果是界面刚初始化，为了防止界面卡顿，可先在后台把需要显示的用户资料和群组资料在后台加载好，然后再刷新界面
                            msgLoaded = true;
                            if (isAdded()) {
                                onRecentContactsLoaded(recents);
                            }
                        }
                    });
        }, 0);
    }


    private void initCallBack() {
        if (callback != null) {
            return;
        }
        callback = new RecentContactsCallback() {

            @Override
            public void onRecentContactsLoaded() {
                //数据加载完成
                jzzLinear.setVisibility(View.GONE);
            }

            @Override
            public void onUnreadCountChange(int unreadCount) {
            }

            @Override
            public void onItemClick(RecentContact recent) {
                if (recent.getSessionType() == SessionTypeEnum.P2P) {
                    if (recent.getContactId().equals("3d51dcd2f116464eabfa546233e3e804")) {
                        RxActivityTool.skipActivity(getContext(), PushMsgActivity.class);
                    } else {
                        NimUIKit.startP2PSession(getActivity(), recent.getContactId());
                    }
                }
            }

            @Override
            public String getDigestOfAttachment(RecentContact recentContact, MsgAttachment attachment) {
                return null;
            }

            @Override
            public String getDigestOfTipMsg(RecentContact recent) {
                return null;
            }
        };
    }

    private SimpleClickListener<RecentContactAdapter> touchListener = new SimpleClickListener<RecentContactAdapter>() {

        @Override
        public void onItemClick(RecentContactAdapter adapter, View view, int position) {
            if (callback != null) {
                RecentContact recent = adapter.getItem(position);
                callback.onItemClick(recent);
            }
        }

        @Override
        public void onItemLongClick(RecentContactAdapter adapter, View view, int position) {
            showLongClickMenu(adapter.getItem(position), position);
        }

        @Override
        public void onItemChildClick(RecentContactAdapter adapter, View view, int position) {
        }

        @Override
        public void onItemChildLongClick(RecentContactAdapter adapter, View view, int position) {
        }
    };

    OnlineStateChangeObserver onlineStateChangeObserver = accounts -> adapter.notifyDataSetChanged();

    private void registerOnlineStateChangeListener(boolean register) {
        if (!NimUIKitImpl.enableOnlineState()) {
            return;
        }
        NimUIKitImpl.getOnlineStateChangeObservable().registerOnlineStateChangeListeners(onlineStateChangeObserver,
                register);
    }

    private void showLongClickMenu(final RecentContact recent, final int position) {
        CustomAlertDialog alertDialog = new CustomAlertDialog(getActivity());
        alertDialog.setTitle(UserInfoHelper.getUserTitleName(recent.getContactId(), recent.getSessionType()));
        String title = getString(R.string.main_msg_list_delete_chatting);
        alertDialog.setTitleVisible(false);
        alertDialog.addItem(title, () -> {
            // 删除会话，删除后，消息历史被一起删除
            NIMClient.getService(MsgService.class).deleteRecentContact(recent);
            NIMClient.getService(MsgService.class).clearChattingHistory(recent.getContactId(), recent.getSessionType());
//            adapter.remove(position);
            postRunnable(() -> deleteContact(position));
        });
//        title = (CommonUtil.isStickyTagSet(recent) ? getString(
//                R.string.main_msg_list_clear_sticky_on_top) : getString(R.string.main_msg_list_sticky_on_top));
//        alertDialog.addItem(title, () -> {
//            if (CommonUtil.isStickyTagSet(recent)) {
//                CommonUtil.removeStickTag(recent);
//            } else {
//                CommonUtil.addStickyTag(recent);
//            }
//            NIMClient.getService(MsgService.class).updateRecent(recent);
//            zhiDing(recent,position);
//        });
        alertDialog.show();
    }

    private RecentContact systemRecentContact;

    private RecentContact getSystemRecentContact(int unreadNum) {
        systemRecentContact = new RecentContact() {
            @Override
            public String getContactId() {
                return "3d51dcd2f116464eabfa546233e3e804";
            }

            @Override
            public String getFromAccount() {
                return null;
            }

            @Override
            public String getFromNick() {
                return "系统消息";
            }

            @Override
            public SessionTypeEnum getSessionType() {
                return SessionTypeEnum.P2P;
            }

            @Override
            public String getRecentMessageId() {
                return "test";
            }

            @Override
            public MsgTypeEnum getMsgType() {
                return MsgTypeEnum.text;
            }

            @Override
            public MsgStatusEnum getMsgStatus() {
                return null;
            }

            @Override
            public void setMsgStatus(MsgStatusEnum msgStatusEnum) {

            }

            @Override
            public int getUnreadCount() {
                return unreadNum;
            }

            @Override
            public String getContent() {
                if (unreadNum == 0) {
                    return "暂无新通知消息";
                } else {
                    return "你有" + unreadNum + "条系统消息";
                }
            }

            @Override
            public long getTime() {
                return System.currentTimeMillis() - 10 * 60 * 1000l;
            }

            @Override
            public MsgAttachment getAttachment() {
                return null;
            }

            @Override
            public void setTag(long l) {

            }

            @Override
            public long getTag() {
                return 0;
            }

            @Override
            public Map<String, Object> getExtension() {
                return null;
            }

            @Override
            public void setExtension(Map<String, Object> map) {

            }
        };
        return systemRecentContact;
    }

    private void onRecentContactsLoaded(List<RecentContact> loadedRecents) {
        RecentContact sysContact = null;
        items.clear();
        for(int i=0;i<loadedRecents.size();i++){
            if(loadedRecents.get(i).getContactId().equals("3d51dcd2f116464eabfa546233e3e804")){
                sysContact = loadedRecents.get(i);
                loadedRecents.remove(i);
                break;
            }
        }
        items.addAll(loadedRecents);
        refreshMessages(true,sysContact,3);
        if (callback != null) {
            //最近联系人列表数据加载完成的回调函数
            callback.onRecentContactsLoaded();
        }
    }


    /**
     * 一键清空聊天消息
     */
    private void clearContact() {
        int deleteNum = 0;
        RecentContact sysObj = items.get(0);
        for (int i = 1; i < items.size(); i++) {
            NIMClient.getService(MsgService.class).deleteRecentContact(items.get(i));
            NIMClient.getService(MsgService.class).clearChattingHistory(items.get(i).getContactId(), items.get(i).getSessionType());
            deleteNum += items.get(i).getUnreadCount();
        }
        items.clear();
        items.add(sysObj);

        if (deleteNum != 0) {
            totalUnReadNum -= deleteNum;
            if (totalUnReadNum == 0) {
                tvUnread.setVisibility(View.INVISIBLE);
            } else if (totalUnReadNum > 99) {
                tvUnread.setVisibility(View.VISIBLE);
                tvUnread.setText("99+");
            } else {
                tvUnread.setVisibility(View.VISIBLE);
                tvUnread.setText(String.valueOf(totalUnReadNum));
            }
            // 方式二：直接从SDK读取（相对慢）
            //int unreadNum = NIMClient.getService(MsgService.class).getTotalUnreadCount();
            if (callback != null) {
                //有未读数更新时的回调函数，供更新除最近联系人列表外的其他界面和未读指示
                callback.onUnreadCountChange(totalUnReadNum);
            }
            Badger.updateBadgerCount(totalUnReadNum);
            title.setText("消息(" + totalUnReadNum + ")");
        }
        adapter.notifyDataSetChanged();
    }

    /**
     * 删除单个聊天信息
     *
     * @param position
     */
    private void deleteContact(int position) {
        RecentContact removeObj = items.get(position);
        if (removeObj.getUnreadCount() != 0) {
            totalUnReadNum -= removeObj.getUnreadCount();
            if (totalUnReadNum == 0) {
                tvUnread.setVisibility(View.INVISIBLE);
            } else if (totalUnReadNum > 99) {
                tvUnread.setVisibility(View.VISIBLE);
                tvUnread.setText("99+");
            } else {
                tvUnread.setVisibility(View.VISIBLE);
                tvUnread.setText(String.valueOf(totalUnReadNum));
            }
            // 方式二：直接从SDK读取（相对慢）
            //int unreadNum = NIMClient.getService(MsgService.class).getTotalUnreadCount();
            if (callback != null) {
                //有未读数更新时的回调函数，供更新除最近联系人列表外的其他界面和未读指示
                callback.onUnreadCountChange(totalUnReadNum);
            }
            Badger.updateBadgerCount(totalUnReadNum);
            title.setText("消息(" + totalUnReadNum + ")");
        }
        adapter.remove(position);
    }


    private int getUnreadNumber() {
        NoticeUnreadNumber unreadNumber = new Gson().fromJson(keyAndValueEntity.getValue(), NoticeUnreadNumber.class);
        return unreadNumber.getGzNum() + unreadNumber.getPlNum() + unreadNumber.getZanNum() + unreadNumber.getXttzNum() + unreadNumber.getWishNum();
    }

    private int totalUnReadNum = 0;
    private void refreshMessages(boolean unreadChanged,RecentContact sysContact,int i) {
        NoticeUnreadNumber nurNumber = new Gson().fromJson(keyAndValueEntity.getValue(), NoticeUnreadNumber.class);
        int gzNum = nurNumber.getGzNum();
        int zanNum = nurNumber.getZanNum();
        int plNum = nurNumber.getPlNum();
        int wishNum = nurNumber.getWishNum();
        int xttzNum = nurNumber.getXttzNum();

        Log.i("from1Data"+i,keyAndValueEntity.getValue());

        if(sysContact != null){
            if (sysContact.getContent().startsWith("点赞：")) {
                zanNum += 1;
            } else if (sysContact.getContent().startsWith("评论：")) {
                plNum += 1;
            } else if (sysContact.getContent().startsWith("关注：")) {
                gzNum += 1;
            } else if (sysContact.getContent().startsWith("愿望：")) {
                wishNum += 1;
            } else {
                xttzNum += 1;
            }
            Intent intent = new Intent("NUM_CHANGE");
            getActivity().sendBroadcast(intent);

            nurNumber.setGzNum(gzNum);
            nurNumber.setZanNum(zanNum);
            nurNumber.setPlNum(plNum);
            nurNumber.setWishNum(wishNum);
            nurNumber.setXttzNum(xttzNum);
            keyAndValueEntity.setValue(new Gson().toJson(nurNumber));
            APP.getKeyAndValueEntityDao().update(keyAndValueEntity);

            NIMClient.getService(MsgService.class).deleteRecentContact(sysContact);
            NIMClient.getService(MsgService.class).clearChattingHistory(sysContact.getContactId(), sysContact.getSessionType());
        }else{
            if(items.size() > 0 && items.get(0).getContactId().equals("3d51dcd2f116464eabfa546233e3e804")){
                items.remove(0);
            }
        }
        if(items.size()>1){
            sortRecentContacts(items);
        }

        totalUnReadNum = gzNum + plNum + zanNum + wishNum + xttzNum;
        systemRecentContact = getSystemRecentContact(getUnreadNumber());
        items.add(0, systemRecentContact);
        adapter.notifyDataSetChanged();
        if (unreadChanged) {
            // 方式一：累加每个最近联系人的未读（快）
            for (RecentContact r : items) {
                if (!r.getContactId().equals("3d51dcd2f116464eabfa546233e3e804")) {
                    totalUnReadNum += r.getUnreadCount();
                }
            }
            if (totalUnReadNum == 0) {
                tvUnread.setVisibility(View.INVISIBLE);
            } else if (totalUnReadNum > 99) {
                tvUnread.setVisibility(View.VISIBLE);
                tvUnread.setText("99+");
            } else {
                tvUnread.setVisibility(View.VISIBLE);
                tvUnread.setText(String.valueOf(totalUnReadNum));
            }
            if (callback != null) {
                //有未读数更新时的回调函数，供更新除最近联系人列表外的其他界面和未读指示
                callback.onUnreadCountChange(totalUnReadNum);
            }
            Badger.updateBadgerCount(totalUnReadNum);
            title.setText("消息(" + totalUnReadNum + ")");
        }
    }

    /**
     * **************************** 排序 ***********************************
     */
    private void sortRecentContacts(List<RecentContact> list) {
        if (list.size() == 0) {
            return;
        }
        Collections.sort(list, comp);
    }

    private static Comparator<RecentContact> comp = (o1, o2) -> {
        // 先比较置顶tag
        long sticky = (o1.getTag() & CommonUtil.RECENT_TAG_STICKY) - (o2.getTag() & CommonUtil.RECENT_TAG_STICKY);
        if (sticky != 0) {
            return sticky > 0 ? -1 : 1;
        } else {
            long time = o1.getTime() - o2.getTime();
            return time == 0 ? 0 : (time > 0 ? -1 : 1);
        }
    };

    /**
     * ********************** 收消息，处理状态变化 ************************
     */
    private void registerObservers(boolean register) {
        MsgServiceObserve service = NIMClient.getService(MsgServiceObserve.class);
        service.observeRecentContact(messageObserver, register);
        service.observeMsgStatus(statusObserver, register);
        if (register) {
            registerUserInfoObserver();
        } else {
            unregisterUserInfoObserver();
        }
    }


    Observer<List<RecentContact>> messageObserver = new Observer<List<RecentContact>>() {

        @Override
        public void onEvent(List<RecentContact> recentContacts) {
            if (recentContacts != null && recentContacts.size() > 0) {
                onRecentContactChanged(recentContacts);
            }
        }
    };

    private void onRecentContactChanged(List<RecentContact> recentContacts) {
        if (items.size() == 0) {
            return;
        }
        int index;
        RecentContact systemContact = null;
        for (RecentContact r : recentContacts) {
            index = -1;
            if(r.getContactId().equals("3d51dcd2f116464eabfa546233e3e804")){
                systemContact = r;
            }
            for (int i = 0; i < items.size(); i++) {
                if (r.getContactId().equals(items.get(i).getContactId())) {
                    index = 100;
                    if(items.get(i).getContactId().equals("3d51dcd2f116464eabfa546233e3e804")){
                        items.remove(i);
                    }else{
                        items.set(i,r);
                    }
                    break;
                }
            }
            if (index == -1) {
                items.add(1, r);
            }
        }
        Log.i("from1","1");
        refreshMessages(true,systemContact,0);
    }

    Observer<IMMessage> statusObserver = new Observer<IMMessage>() {

        @Override
        public void onEvent(IMMessage message) {
            int index = getItemIndex(message.getUuid());
            if (index >= 0 && index < items.size()) {
                RecentContact item = items.get(index);
                item.setMsgStatus(message.getStatus());
                refreshViewHolderByIndex(index);
            }
        }
    };

    private int getItemIndex(String uuid) {
        for (int i = 0; i < items.size(); i++) {
            RecentContact item = items.get(i);
            if (TextUtils.equals(item.getRecentMessageId(), uuid)) {
                return i;
            }
        }
        return -1;
    }

    protected void refreshViewHolderByIndex(final int index) {
        getActivity().runOnUiThread(() -> adapter.notifyItemChanged(index));
    }

    public void setCallback(RecentContactsCallback callback) {
        this.callback = callback;
    }

    private void registerUserInfoObserver() {
        if (userInfoObserver == null) {
            userInfoObserver = accounts -> refreshMessages(false,null,1);
        }
        NimUIKit.getUserInfoObservable().registerObserver(userInfoObserver, true);
    }

    private void unregisterUserInfoObserver() {
        if (userInfoObserver != null) {
            NimUIKit.getUserInfoObservable().registerObserver(userInfoObserver, false);
        }
    }

    private void updateOfflineContactAited(final RecentContact recentContact) {
        if (recentContact == null || recentContact.getSessionType() != SessionTypeEnum.Team ||
                recentContact.getUnreadCount() <= 0) {
            return;
        }
        // 锚点
        List<String> uuid = new ArrayList<>(1);
        uuid.add(recentContact.getRecentMessageId());
        List<IMMessage> messages = NIMClient.getService(MsgService.class).queryMessageListByUuidBlock(uuid);
        if (messages == null || messages.size() < 1) {
            return;
        }
        final IMMessage anchor = messages.get(0);
        // 查未读消息
        NIMClient.getService(MsgService.class).queryMessageListEx(anchor, QueryDirectionEnum.QUERY_OLD,
                recentContact.getUnreadCount() - 1, false)
                .setCallback(new RequestCallbackWrapper<List<IMMessage>>() {

                    @Override
                    public void onResult(int code, List<IMMessage> result, Throwable exception) {
                        if (code == ResponseCode.RES_SUCCESS && result != null) {
                            result.add(0, anchor);
                            Set<IMMessage> messages = null;
                            // 过滤存在的@我的消息
                            for (IMMessage msg : result) {
                                if (TeamMemberAitHelper.isAitMessage(msg)) {
                                    if (messages == null) {
                                        messages = new HashSet<>();
                                    }
                                    messages.add(msg);
                                }
                            }
                            // 更新并展示
                            if (messages != null) {
                                TeamMemberAitHelper.setRecentContactAited(recentContact, messages);
                                adapter.notifyDataSetChanged();
                            }
                        }
                    }
                });

    }

    public void setData(int total, int totalAll) {
        msgTip.setText(total + "");
        title.setText("消息(" + totalAll + ")");
        Badger.updateBadgerCount(total);
        msgTip.setVisibility(total == 0 ? View.INVISIBLE : View.VISIBLE);
    }

    @Override
    public void onResume() {
        super.onResume();
        if(items.size() > 0){
            refreshMessages(true,null,2);
        }
    }
}
